#include "server_core.hpp"
#include "../common/thread_pool.hpp"
#include "../common/user_manager.hpp"
#include "../common/room_manager.hpp"
#include <string>
#include <unistd.h>
#include <sys/socket.h>
#include <iostream>
#include <sstream>

static ThreadPool* pool = nullptr;
static const int admin_fd = 4;
const std::string ADMIN_NAME = "tbx";
const std::string ADMIN_PASSWORD = "151211";
std::unordered_map<int, bool> pending_admin_auth;

void init_server_core(ThreadPool* p) {
    pool = p;
}

void register_client(int fd) {
    user_manager.add_user(fd);
    std::cout << "[Server] New connection: fd=" << fd << std::endl;
    std::string ask_name = "[Server] Please enter your nickname:\n";
    send(fd, ask_name.c_str(), ask_name.size(), 0);
}


void unregister_client(int fd) {
    std::string name = user_manager.get_name(fd);
    std::string msg = "[Server] " + name + " left the chat.\n";
    for (int client : user_manager.get_all_fds()) {
        if (client != fd) {
            send(client, msg.c_str(), msg.size(), 0);
        }
    }
    std::cout << msg;
    user_manager.remove_user(fd);
    close(fd);
}

void handle_client_message(int fd, const std::string& msg) {
    pool->enqueue([fd, msg]() {
            if (user_manager.get_name(fd) == "anonymous") {
              if (user_manager.name_exists(msg)) {
                 std::string err = "[Server] This nickname is already taken.\n[Server] Please enter a different nickname:\n";
                 send(fd, err.c_str(), err.size(), 0);
                 return;
            }
            // 若为设定管理员名，则进入密码验证阶段
            if (msg == ADMIN_NAME) {
                pending_admin_auth[fd] = true;
                user_manager.rename_user(fd, ADMIN_NAME);
                std::string prompt = "[Server] Enter admin password:\n";
                send(fd, prompt.c_str(), prompt.size(), 0);
                return;
            }
            //  检查该名字是否被封禁
            if (user_manager.is_banned(msg)) {
                std::string notice = "[Server] You are banned.\n";
                send(fd, notice.c_str(), notice.size(), 0);
                unregister_client(fd); // 断开连接
                return;
            }
            user_manager.rename_user(fd, msg);
            std::string welcome = "[Server] Welcome, " + msg + "!\n";
            send(fd, welcome.c_str(), welcome.size(), 0);

            std::string notice = "[Server] " + msg + " joined the chat.\n";
            for (int client : user_manager.get_all_fds()) {
                if (client != fd) {
                    send(client, notice.c_str(), notice.size(), 0);
                }
            }
            std::cout << notice;
            return;
        }
        // 正在等待管理员密码
        if (pending_admin_auth.count(fd)) {
            if (msg == ADMIN_PASSWORD) {
                user_manager.add_admin(fd);
                std::string ok = "[Server] Admin login successful.\n";
                send(fd, ok.c_str(), ok.size(), 0);
            } else {
                std::string fail = "[Server] Wrong password. You are not admin.\n";
                send(fd, fail.c_str(), fail.size(), 0);
                user_manager.rename_user(fd, "anonymous");  // 清空名称重新输入
                std::string ask_name = "[Server] Please enter your nickname:\n";
                send(fd, ask_name.c_str(), ask_name.size(), 0);
            }
            pending_admin_auth.erase(fd);
            return;
        }

        if (msg == "/who") {
            std::string list = "[Server] Online users:\n";
            for (int client : user_manager.get_all_fds()) {
                list += " - " + user_manager.get_name(client) + "\n";
            }
            send(fd, list.c_str(), list.size(), 0);
            return;
        }
        else if (msg.rfind("/rename ", 0) == 0) {
                std::string newname = msg.substr(8);
                if (newname.empty()) {
                        std::string err = "[Server] Usage: /rename <newname>\n";
                        send(fd, err.c_str(), err.size(), 0);
                        return;
                }
                if (user_manager.name_exists(newname)) {
                        std::string err = "[Server] This name is already taken.\n";
                        send(fd, err.c_str(), err.size(), 0);
                        return;
                }
                if (newname == "tbx") {
                        pending_admin_auth[fd] = "tbx";  // 等待输入管理员密码
                        std::string ask = "[Server] Enter admin password to rename:\n";
                        send(fd, ask.c_str(), ask.size(), 0);
                        return;
                }
                std::string oldname = user_manager.get_name(fd);
                user_manager.rename_user(fd, newname);
                std::string ack = "[Server] Your name is now " + newname + ".\n";
                send(fd, ack.c_str(), ack.size(), 0);
                std::string notice = "[Server] " + oldname + " is now known as " + newname + ".\n";
                for (int client : user_manager.get_all_fds()) {
                        if (client != fd) {
                                send(client, notice.c_str(), notice.size(), 0);
                        }
                }
                std::cout << notice;
                return;
        }
        else if (msg == "/adminlist") {
            std::string list = "[Server] Admins online:\n";
            for (int client : user_manager.get_all_fds()) {
                if (user_manager.is_admin(client)) {
                    list += " - " + user_manager.get_name(client) + "\n";
                }
            }
            send(fd, list.c_str(), list.size(), 0);
            return;
        }
        else if (msg.rfind("/kick ", 0) == 0) {
            std::istringstream iss(msg);
            std::string cmd, target;
            iss >> cmd >> target;

            if (!user_manager.is_admin(fd)) {
                std::string err = "[Server] You are not authorized to kick users.\n";
                send(fd, err.c_str(), err.size(), 0);
                return;
            }

            int target_fd = user_manager.get_fd_by_name(target);
            if (target_fd == -1) {
                std::string err = "[Server] User not found.\n";
                send(fd, err.c_str(), err.size(), 0);
                return;
            }

            std::string notice = "[Server] You have been kicked from the chat.\n";
            send(target_fd, notice.c_str(), notice.size(), 0);

            std::string broadcast = "[Server] User " + target + " was kicked by admin.\n";
            for (int client : user_manager.get_all_fds()) {
                if (client != target_fd) {
                    send(client, broadcast.c_str(), broadcast.size(), 0);
                }
            }

            unregister_client(target_fd);
            return;
        }
        else if (msg.rfind("/mute ", 0) == 0) {
    if (!user_manager.is_admin(fd)) {
        std::string err = "[Server] You are not authorized to mute users.\n";
        send(fd, err.c_str(), err.size(), 0);
        return;
    }

    std::string target = msg.substr(6);
    int target_fd = user_manager.get_fd_by_name(target);
    if (target_fd == -1) {
        std::string err = "[Server] User not found.\n";
        send(fd, err.c_str(), err.size(), 0);
        return;
    }

    user_manager.mute_user(target_fd);
    std::string notice = "[Server] " + target + " has been muted.\n";
    send(fd, notice.c_str(), notice.size(), 0);
    return;
}

else if (msg.rfind("/unmute ", 0) == 0) {
    if (!user_manager.is_admin(fd)) {
        std::string err = "[Server] You are not authorized to unmute users.\n";
        send(fd, err.c_str(), err.size(), 0);
        return;
    }

    std::string target = msg.substr(8);
    int target_fd = user_manager.get_fd_by_name(target);
    if (target_fd == -1) {
        std::string err = "[Server] User not found.\n";
        send(fd, err.c_str(), err.size(), 0);
        return;
    }

    user_manager.unmute_user(target_fd);
    std::string notice = "[Server] " + target + " has been unmuted.\n";
    send(fd, notice.c_str(), notice.size(), 0);
    return;
}
        else if (msg.rfind("/ban ", 0) == 0) {
        if (!user_manager.is_admin(fd)) {
                std::string err = "[Server] You are not authorized to ban users.\n";
                send(fd, err.c_str(), err.size(), 0);
                return;
        }

        std::string target = msg.substr(5);
        int target_fd = user_manager.get_fd_by_name(target);
        if (target_fd == -1) {
                std::string err = "[Server] User not found.\n";
                send(fd, err.c_str(), err.size(), 0);
                return;
        }

        user_manager.ban_user(target);
        std::string notice = "[Server] " + target + " has been banned.\n";
        send(fd, notice.c_str(), notice.size(), 0);
        unregister_client(target_fd);
        return;
        }

        else if (msg.rfind("/unban ", 0) == 0) {
        if (!user_manager.is_admin(fd)) {
                std::string err = "[Server] You are not authorized to unban users.\n";
                send(fd, err.c_str(), err.size(), 0);
                return;
        }

        std::string target = msg.substr(7);
        user_manager.unban_user(target);
        std::string notice = "[Server] " + target + " has been unbanned.\n";
        send(fd, notice.c_str(), notice.size(), 0);
        return;
        }
 
        else if (msg == "/quit") {
            std::string notice = "[Server] You have disconnected.\n";
            send(fd, notice.c_str(), notice.size(), 0);
            unregister_client(fd);
            return;
        }
        else if (msg.substr(0, 6) == "/join ") {
            std::istringstream iss(msg);
            std::string cmd, room, pwd;
            iss >> cmd >> room >> pwd;

            bool success = room_manager.join_room(fd, room, pwd);
            if (success) {
                 std::string notice = "[Server] You joined room: " + room + "\n";
                 send(fd, notice.c_str(), notice.size(), 0);
            }
            return;
        }
        else if (msg == "/leave") {
            room_manager.leave_room(fd);
            std::string left = "[Server] You left the room.\n";
            send(fd, left.c_str(), left.size(), 0);
            return;
        }
        else if (msg == "/members") {
            std::string room = room_manager.get_room(fd);
            std::set<int> members = room_manager.get_room_members(room);
            std::string output = "[Server] Room: " + room + "\n[Server] Members:\n";
            for (int member_fd : members) {
                    output += " - " + user_manager.get_name(member_fd) + "\n";
            }
            send(fd, output.c_str(), output.size(), 0);
            return;
        }
        else if (msg == "/room") {
            std::string room = room_manager.get_room(fd);
            if (room.empty()) {
                room = "lobby";
            }
            std::string output = "[Server] You are in room: " + room + "\n";
            send(fd, output.c_str(), output.size(), 0);
            return;
        }
         else if (msg.rfind("/to ", 0) == 0) {
            std::istringstream iss(msg);
            std::string cmd, target, word;
            iss >> cmd >> target;
            std::string message;
            while (iss >> word) message += word + " ";
            int target_fd = user_manager.get_fd_by_name(target);
            if (user_manager.is_muted(fd)) {
                std::string err = "[Server] You are muted and cannot send private messages.\n";
                send(fd, err.c_str(), err.size(), 0);
                return;
            }
            if (target_fd != -1) {
                std::string out = "[PM from " + user_manager.get_name(fd) + "]: " + message + "\n";
                send(target_fd, out.c_str(), out.size(), 0);
            } else {
                std::string err = "[Server] User not found.\n";
                send(fd, err.c_str(), err.size(), 0);
            }
            return;
        }
        
        if (user_manager.is_muted(fd)) {
            std::string err = "[Server] You are muted and cannot send messages.\n";
            send(fd, err.c_str(), err.size(), 0);
            return;
        }
        std::string output = "[" + user_manager.get_name(fd) + "]: " + msg + "\n";
        for (int client : user_manager.get_all_fds()) {
            if (client != fd) {
                send(client, output.c_str(), output.size(), 0);
            }
        }
    });
}

